﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace PubSubSocketServer
{
    public partial class PubSubServerUI : Form
    {
        private static PubMessage pm = new PubMessage();
        private static string _PubIP;
        private static int _PubPortNo;
        private static string _SubIP;
        private static int _SubPortNo;
        
        // This delegate enables asynchronous calls for setting
        // the text property on a TextBox control.
        private delegate void SetTextCallback(string text, TextBox txtbox);

        //private Dictionary<string, string> topicList = new Dictionary<string, string>();

        public PubSubServerUI()
        {
            InitializeComponent();
            //HostPublishSubscribeServices();
            //pm.MessageChanged += UpdateMessageChanged;
        }

        private static void HostPublishSubscribeServices()
        {
            SubscriberService subscriberService = new SubscriberService(_SubIP, _SubPortNo);
            subscriberService.StartSubscriberService();

            PublisherService publisherService = new PublisherService(pm, _PubIP, _PubPortNo);
            publisherService.StartPublisherService();
        }

        //public void addTopic(string key, string topicString)
        //{
        //    topicList.Add(key, topicString);
        //}

        private void UpdateMessageChanged(object sender, MessageChangedArgs args)
        {
            // Check if this method is running on a different thread
            // than the thread that created the control.
            if (this.txtData.InvokeRequired)
            {
                // It's on a different thread, so use Invoke.
                SetTextCallback st = new SetTextCallback(SetText);
                this.Invoke(st, new object[] {args.message, this.txtData });
            }
            else
            {
                // It's on the same thread, no need for Invoke
                this.txtData.AppendText(args.message + Environment.NewLine);
            }            
        }

        // This method is passed in to the SetTextCallBack delegate to set the Text property of Label lbl
        private void SetText(string text, TextBox txtbox)
        {
            string [] lines = txtbox.Lines;
            //if (lines.Length < 20)
            //{
                txtbox.AppendText(text + Environment.NewLine);
            //}
            //else
            //{
            //    bool firstline = true;
            //    txtbox.Clear();
            //    foreach (string l in lines) 
            //    {
            //        if (firstline)
            //        {
            //            firstline = false;
            //        }
            //        else
            //        {
            //            txtbox.AppendText(l);
            //        }
            //    }
            //    txtbox.AppendText(text + Environment.NewLine);
            //}
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            _PubIP = this.txtPubIPAdd.Text;
            _PubPortNo = int.Parse(this.txtPubPortNo.Text);
            _SubIP = this.txtSubIPAdd.Text;
            _SubPortNo = int.Parse(this.txtSubPortNo.Text);
            HostPublishSubscribeServices();
            pm.MessageChanged += UpdateMessageChanged;
            lblStatus.Text = "Services Started";
        }
    }

    public class PubMessage
    {
        private string _message;
        public EventHandler<MessageChangedArgs> MessageChanged; 

        public string Message
        {
            get
            {
                return _message;
            }
            set
            {
                _message = value;
                if (this.MessageChanged != null)
                {
                    this.MessageChanged(this, new MessageChangedArgs(_message));
                }
            }
        }
    }

    public class MessageChangedArgs : EventArgs
    {
        public string message;

        public MessageChangedArgs(string message)
        {
            this.message = message;
        }
    }

}
